#include "TCPScanner.h"
#include <iostream>
#include <winsock2.h>
#include <winsock.h>
#include <pcap.h>
#include <stdlib.h>
#include <Iphlpapi.h>
#include <ThreadPool.h>
#include "Common.h"
#include <QsLog.h>
using namespace std;

#define IPAddress "10.4.16.113"

char HostIPAddress[256] = {0};

// 打开网卡返回的指针
pcap_t* m_adhandle = NULL;
unsigned char* FinalPacket = NULL;
unsigned int UserDataLen;
// bpf_program fcode;
u_int netmask;
std::string m_gateIPAddress;

char SourceMAC[MAX_PATH] = {0};
char SourceIP[MAX_PATH] = IPAddress;
char SourcePort[MAX_PATH] = "1234";

char DestinationMAC[MAX_PATH] = {0};

// 输出线条
void PrintLine(int x)
{
    for (size_t i = 0; i < x; i++)
    {
        printf("-");
    }
    printf("\n");
}

// 枚举当前网卡
int enumAdapters()
{
    pcap_if_t *allAdapters;    // 所有网卡设备保存
    pcap_if_t *ptr;            // 用于遍历的指针
    int index = 0;
    char errbuf[PCAP_ERRBUF_SIZE];

    /* 获取本地机器设备列表 */
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &allAdapters, errbuf) != -1)
    {
        PrintLine(100);
        printf("索引 \t 网卡名 \n");
        PrintLine(100);

        /* 打印网卡信息列表 */
        for (ptr = allAdapters; ptr != NULL; ptr = ptr->next)
        {
            ++index;
            if (ptr->description)
            {
                printf("[ %d ] \t [ %s ] \n", index - 1, ptr->description);
            }
        }
    }

    /* 不再需要设备列表了，释放它 */
    pcap_freealldevs(allAdapters);
    return index;
}

// 通过传入本机IP地址打开网卡
void OpenAdapter(std::string local_address)
{
    pcap_if_t* alldevs = NULL, * d = NULL;
    char errbuf[256] = { 0 };

    // 获取网卡设备指针
    if (-1 == pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf))
    {
        std::cout << "获取网卡设备指针出错" << std::endl;
        return;
    }

    // 选取适合网卡
    int flag = 0;
    for (d = alldevs; d; d = d->next)
    {
        std::cout << d->name << "\n" << d->description << std::endl;
        pcap_addr_t* p = d->addresses;
        while (p)
        {
            std::cout << inet_ntoa(((sockaddr_in*)p->addr)->sin_addr) << std::endl;
            if (local_address == inet_ntoa(((sockaddr_in*)p->addr)->sin_addr))
            {
                flag = 1;
                break;
            }
            p = p->next;
        }
        if (1 == flag)
            break;
    }
    if (0 == flag)
    {
        std::cout << "请检查本机IP地址是否正确" << std::endl;
        std::cout << local_address.c_str() << std::endl;
        return;
    }

    // 获取子网掩码
    netmask = ((sockaddr_in*)d->addresses->netmask)->sin_addr.S_un.S_addr;

    // 打开网卡
    m_adhandle = pcap_open(d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf);
    if (NULL == m_adhandle)
    {
        std::cout << "打开网卡出错" << std::endl;
        pcap_freealldevs(alldevs);
        return;
    }

    //检查以太网
    if (DLT_EN10MB != pcap_datalink(m_adhandle))
    {
        std::cout << "此程序仅在以太网下工作" << std::endl;
        pcap_freealldevs(alldevs);
        return;
    }

    // 释放网卡设备列表
    pcap_freealldevs(alldevs);
}

unsigned short checksum(unsigned short* addr, int len)
{
    int nleft = len;
    int sum = 0;
    unsigned short* w = addr;
    unsigned short answer = 0;

    while (nleft > 1)
    {
        sum += *w++;
        nleft -= 2;
    }

    if (nleft == 1)
    {
        *(unsigned char*)(&answer) = *(unsigned char*)w;
        sum += answer;
    }

    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    answer = ~sum;
    return(answer);
}

// MAC地址转Bytes
unsigned char* MACStringToBytes(std::string String)
{
    // 获取输入字符串的长度
    int iLen = strlen(String.c_str());

    // 创建一个临时缓冲区，用于存储输入字符串的拷贝
    char* Tmp = new char[(iLen + 1)];

    // 将输入字符串拷贝到临时缓冲区
    strcpy(Tmp, String.c_str());

    // 创建一个用于存储结果的unsigned char数组，数组大小为6
    unsigned char* Returned = new unsigned char[6];

    // 循环处理每个字节
    for (int i = 0; i < 6; i++)
    {
        // 使用sscanf将字符串中的两个字符转换为16进制数，存储到Returned数组中
        sscanf(Tmp, "%2X", &Returned[i]);

        // 移动临时缓冲区的指针，跳过已经处理过的字符
        memmove((void*)(Tmp), (void*)(Tmp + 3), 19 - i * 3);
    }

    // 返回存储结果的数组
    return Returned;
}

// Bytes地址转16进制
unsigned short BytesTo16(unsigned char X, unsigned char Y)
{
    // 将 X 左移8位，然后与 Y 进行按位或操作，得到一个16位的无符号整数
    unsigned short Tmp = X;
    Tmp = Tmp << 8;
    Tmp = Tmp | Y;
    return Tmp;
}

// 计算IP校验和
unsigned short CalculateIPChecksum(UINT TotalLen, UINT ID, UINT SourceIP, UINT DestIP)
{
    // 初始化校验和
    unsigned short CheckSum = 0;

    // 遍历 IP 头的每两个字节
    for (int i = 14; i < 34; i += 2)
    {
        // 将每两个字节合并为一个16位整数
        unsigned short Tmp = BytesTo16(FinalPacket[i], FinalPacket[i + 1]);

        // 计算校验和
        unsigned short Difference = 65535 - CheckSum;
        CheckSum += Tmp;

        // 处理溢出
        if (Tmp > Difference) { CheckSum += 1; }
    }

    // 取反得到最终的校验和
    CheckSum = ~CheckSum;

    return CheckSum;
}

// 计算UDP校验和
unsigned short CalculateUDPChecksum(unsigned char* UserData, int UserDataLen, UINT SourceIP, UINT DestIP, USHORT SourcePort, USHORT DestinationPort, UCHAR Protocol)
{
    unsigned short CheckSum = 0;

    // 计算 UDP 数据报的伪首部长度
    unsigned short PseudoLength = UserDataLen + 8 + 9; // 长度包括 UDP 头（8字节）和伪首部（9字节）

    // 如果长度不是偶数，添加一个额外的字节
    PseudoLength += PseudoLength % 2;

    // 创建 UDP 伪首部
    unsigned char* PseudoHeader = new unsigned char[PseudoLength];
    RtlZeroMemory(PseudoHeader, PseudoLength);

    // 设置伪首部中的协议字段为 UDP (0x11)
    PseudoHeader[0] = 0x11;

    // 复制源和目标 IP 地址到伪首部
    memcpy((void*)(PseudoHeader + 1), (void*)(FinalPacket + 26), 8);

    // 将 UDP 头的长度字段拷贝到伪首部
    unsigned short Length = UserDataLen + 8;
    Length = htons(Length);
    memcpy((void*)(PseudoHeader + 9), (void*)&Length, 2);
    memcpy((void*)(PseudoHeader + 11), (void*)&Length, 2);

    // 将源端口、目标端口和 UDP 数据拷贝到伪首部
    memcpy((void*)(PseudoHeader + 13), (void*)(FinalPacket + 34), 2);
    memcpy((void*)(PseudoHeader + 15), (void*)(FinalPacket + 36), 2);
    memcpy((void*)(PseudoHeader + 17), (void*)UserData, UserDataLen);

    // 遍历伪首部的每两个字节，计算校验和
    for (int i = 0; i < PseudoLength; i += 2)
    {
        unsigned short Tmp = BytesTo16(PseudoHeader[i], PseudoHeader[i + 1]);
        unsigned short Difference = 65535 - CheckSum;
        CheckSum += Tmp;
        if (Tmp > Difference) { CheckSum += 1; }
    }

    // 取反得到最终的校验和
    CheckSum = ~CheckSum;

    // 释放伪首部的内存
    delete[] PseudoHeader;

    return CheckSum;
}

void CreateUDPPacket(unsigned char* SourceMAC, unsigned char* DestinationMAC,unsigned long SourceIP, unsigned long DestIP,unsigned short SourcePort, unsigned short DestinationPort,unsigned char* UserData, unsigned int UserDataLength)
{
    UserDataLen = UserDataLength;
    FinalPacket = new unsigned char[UserDataLength + 42]; // 为数据长度加上42字节的标头保留足够的内存
    USHORT TotalLen = UserDataLength + 20 + 8;            // IP报头使用数据长度加上IP报头长度（通常为20字节）加上udp报头长度（通常为8字节）

    // 开始填充以太网包头
    memcpy((void*)FinalPacket, (void*)DestinationMAC, 6);
    memcpy((void*)(FinalPacket + 6), (void*)SourceMAC, 6);

    USHORT TmpType = 8;
    memcpy((void*)(FinalPacket + 12), (void*)&TmpType, 2);  // 使用的协议类型(USHORT）类型0x08是UDP。可以为其他协议（例如TCP）更改此设置

    // 开始填充IP头数据包
    memcpy((void*)(FinalPacket + 14), (void*)"\x45", 1);     // 前3位的版本（4）和最后5位的标题长度。
    memcpy((void*)(FinalPacket + 15), (void*)"\x00", 1);     // 通常为0
    TmpType = htons(TotalLen);
    memcpy((void*)(FinalPacket + 16), (void*)&TmpType, 2);

    TmpType = htons(0x1337);
    memcpy((void*)(FinalPacket + 18), (void*)&TmpType, 2);    // Identification
    memcpy((void*)(FinalPacket + 20), (void*)"\x00", 1);      // Flags
    memcpy((void*)(FinalPacket + 21), (void*)"\x00", 1);      // Offset
    memcpy((void*)(FinalPacket + 22), (void*)"\x80", 1);      // Time to live.
    memcpy((void*)(FinalPacket + 23), (void*)"\x11", 1);      // 协议UDP为0x11（17）TCP为6 ICMP为1等
    memcpy((void*)(FinalPacket + 24), (void*)"\x00\x00", 2);  // 计算校验和
    memcpy((void*)(FinalPacket + 26), (void*)&SourceIP, 4);   //inet_addr does htonl() for us
    memcpy((void*)(FinalPacket + 30), (void*)&DestIP, 4);

    // 开始填充UDP头部数据包
    TmpType = htons(SourcePort);
    memcpy((void*)(FinalPacket + 34), (void*)&TmpType, 2);
    TmpType = htons(DestinationPort);
    memcpy((void*)(FinalPacket + 36), (void*)&TmpType, 2);
    USHORT UDPTotalLen = htons(UserDataLength + 8); // UDP Length does not include length of IP header
    memcpy((void*)(FinalPacket + 38), (void*)&UDPTotalLen, 2);
    //memcpy((void*)(FinalPacket+40),(void*)&TmpType,2); //checksum
    memcpy((void*)(FinalPacket + 42), (void*)UserData, UserDataLength);

    unsigned short UDPChecksum = CalculateUDPChecksum(UserData, UserDataLength, SourceIP, DestIP, htons(SourcePort), htons(DestinationPort), 0x11);
    memcpy((void*)(FinalPacket + 40), (void*)&UDPChecksum, 2);

    unsigned short IPChecksum = htons(CalculateIPChecksum(TotalLen, 0x1337, SourceIP, DestIP));
    memcpy((void*)(FinalPacket + 24), (void*)&IPChecksum, 2);

    return;
}

void CreateTCPPacket(unsigned char* SourceMAC, unsigned char* DestinationMAC,unsigned long SourceIP, unsigned long DestIP, unsigned short SourcePort,
                     unsigned short DestinationPort, int flag)
{
    if(FinalPacket)
    {
        delete[] FinalPacket;
        FinalPacket = nullptr;
    }
    FinalPacket = new unsigned char[54]; // 为数据长度加上42字节的标头保留足够的内存
    USHORT TotalLen = 20 + 20;            // IP报头使用数据长度加上IP报头长度（通常为20字节）加上tcp报头长度（通常为20字节）

    // 开始填充以太网包头
    memcpy((void*)FinalPacket, (void*)DestinationMAC, 6);
    memcpy((void*)(FinalPacket + 6), (void*)SourceMAC, 6);

    USHORT TmpType = 8;
    memcpy((void*)(FinalPacket + 12), (void*)&TmpType, 2);  // 使用的协议类型(USHORT）类型0x08是UDP。可以为其他协议（例如TCP）更改此设置

    // 开始填充IP头数据包
    memcpy((void*)(FinalPacket + 14), (void*)"\x45", 1);     // 前3位的版本（4）和最后5位的标题长度。
    memcpy((void*)(FinalPacket + 15), (void*)"\x00", 1);     // 通常为0
    TmpType = htons(TotalLen);
    memcpy((void*)(FinalPacket + 16), (void*)&TmpType, 2);

    TmpType = htons(0x1337);
    memcpy((void*)(FinalPacket + 18), (void*)&TmpType, 2);    // Identification
    memcpy((void*)(FinalPacket + 20), (void*)"\x00", 1);      // Flags
    memcpy((void*)(FinalPacket + 21), (void*)"\x00", 1);      // Offset
    memcpy((void*)(FinalPacket + 22), (void*)"\x80", 1);      // Time to live.
    memcpy((void*)(FinalPacket + 23), (void*)"\x06", 1);      // 协议UDP为0x11（17）TCP为6 ICMP为1等
    memcpy((void*)(FinalPacket + 24), (void*)"\x00\x00", 2);  // 计算校验和，下面计算
    memcpy((void*)(FinalPacket + 26), (void*)&SourceIP, 4);   //inet_addr does htonl() for us
    memcpy((void*)(FinalPacket + 30), (void*)&DestIP, 4);

    // 构造包
    struct _tcphdr tcpHeader;
    struct psd_hdr psdHeader;

    // 填充TCP
    tcpHeader.th_dport = htons(DestinationPort);
    tcpHeader.th_sport = htons(SourcePort);
    tcpHeader.th_seq = htonl(0x12345678);
    tcpHeader.th_ack = 0;
    tcpHeader.th_lenres = (sizeof(tcpHeader) / 4 << 4 | 0);
    tcpHeader.th_flag = flag;
    tcpHeader.th_win = htons(512);
    tcpHeader.th_urp = 0;
    tcpHeader.th_sum = 0;

    //psdheader
    psdHeader.saddr = SourceIP;
    psdHeader.daddr = DestIP;
    psdHeader.mbz = 0;  // mbz = must be zero, 用于填充对齐
    psdHeader.ptcl = IPPROTO_TCP;  //8位协议号
    psdHeader.tcpl = htons(sizeof(tcpHeader));

    char TempBuffer[256];
    memset(TempBuffer, 0, sizeof(TempBuffer));
    //set checksum 使用伪头计算TCP校验和
    memcpy(TempBuffer, &psdHeader, sizeof(psdHeader));
    memcpy(TempBuffer + sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
    tcpHeader.th_sum = checksum((unsigned short*)TempBuffer, sizeof(psdHeader) + sizeof(tcpHeader));

    //最终的组包（TCP+IP）
    memcpy(TempBuffer, &tcpHeader, sizeof(tcpHeader));

    memcpy((void*)(FinalPacket + 34), (void*)&TempBuffer, sizeof(tcpHeader));

    unsigned short IPChecksum = htons(CalculateIPChecksum(TotalLen, 0x1337, SourceIP, DestIP));
    memcpy((void*)(FinalPacket + 24), (void*)&IPChecksum, 2);
}

// 解码TCP数据包，需要先加14跳过数据链路层, 然后再加20跳过IP层。
void PrintTCPHeader(const unsigned char * packetData)
{
    struct tcp_header
    {
        short SourPort;                 // 源端口号16bit
        short DestPort;                 // 目的端口号16bit
        unsigned int SequNum;           // 序列号32bit
        unsigned int AcknowledgeNum;    // 确认号32bit
        unsigned char reserved : 4, offset : 4; // 预留偏移

        unsigned char  flags;               // 标志

        short WindowSize;               // 窗口大小16bit
        short CheckSum;                 // 检验和16bit
        short surgentPointer;           // 紧急数据偏移量16bit
    };

    struct tcp_header *tcp_protocol;
    // +14 跳过数据链路层 +20 跳过IP层
    tcp_protocol = (struct tcp_header *)(packetData + 14 + 20);

    u_short sport = ntohs(tcp_protocol->SourPort);
    u_short dport = ntohs(tcp_protocol->DestPort);
    int window = tcp_protocol->WindowSize;
    int flags = tcp_protocol->flags;

    printf("源端口: %6d --> 目标端口: %6d --> 窗口大小: %7d --> 标志: (%d)",
           sport, dport, window, flags);

    if (flags & 0x08) printf("PSH 数据传输\n");
    if (flags & 0x10) printf("ACK 响应\n");
    if (flags & 0x02) printf("SYN 建立连接\n");
    if (flags & 0x20) printf("URG \n");
    if (flags & 0x01) printf("FIN 关闭连接\n");
    if (flags & 0x04) printf("RST 连接重置\n");
    // else printf("None 未知\n");
}

#define hcons(A) (((WORD)(A)&0xFF00)>>8) | (((WORD)(A)&0x00FF)<<8)

// 输出 数据链路层
void PrintEtherHeader(const u_char * packetData)
{
    struct ether_header {
        u_char ether_dhost[6];    // 目标地址
        u_char ether_shost[6];    // 源地址
        u_short ether_type;       // 以太网类型
    };

    struct ether_header * eth_protocol;
    eth_protocol = (struct ether_header *)packetData;

    u_short ether_type = ntohs(eth_protocol->ether_type);  // 以太网类型
    u_char *ether_src = eth_protocol->ether_shost;         // 以太网原始MAC地址
    u_char *ether_dst = eth_protocol->ether_dhost;         // 以太网目标MAC地址

    printf("类型: 0x%x \t", ether_type);
    printf("原MAC地址: %02X:%02X:%02X:%02X:%02X:%02X \t",
           ether_src[0], ether_src[1], ether_src[2], ether_src[3], ether_src[4], ether_src[5]);
    printf("目标MAC地址: %02X:%02X:%02X:%02X:%02X:%02X \n",
           ether_dst[0], ether_dst[1], ether_dst[2], ether_dst[3], ether_dst[4], ether_dst[5]);
}

void PrintIPHeader(const u_char * packetData)
{
    struct ip_header *ip_protocol;

    // +14 跳过数据链路层
    ip_protocol = (struct ip_header *)(packetData + 14);
    SOCKADDR_IN Src_Addr, Dst_Addr = { 0 };

    u_short check_sum = ntohs(ip_protocol->check_sum);
    int ttl = ip_protocol->time_to_live;
    int proto = ip_protocol->Protocol;

    Src_Addr.sin_addr.s_addr = ip_protocol->SrcAddr;
    Dst_Addr.sin_addr.s_addr = ip_protocol->DstAddr;

    printf("源地址: %15s --> ", inet_ntoa(Src_Addr.sin_addr));
    printf("目标地址: %15s --> ", inet_ntoa(Dst_Addr.sin_addr));

    printf("校验和: %5X --> TTL: %4d --> 协议类型: ", check_sum, ttl);
    switch (ip_protocol->Protocol)
    {
    case 1: printf("ICMP \n"); break;
    case 2: printf("IGMP \n"); break;
    case 6: printf("TCP \n");  break;
    case 17: printf("UDP \n"); break;
    case 89: printf("OSPF \n"); break;
    default: printf("None \n"); break;
    }
}

void PrintUDPHeader(const unsigned char * packetData)
{
    struct udp_header {
        uint32_t sport;   // 源端口
        uint32_t dport;   // 目标端口
        uint8_t zero;     // 保留位
        uint8_t proto;    // 协议标识
        uint16_t datalen; // UDP数据长度
    };

    struct udp_header *udp_protocol;
    // +14 跳过数据链路层 +20 跳过IP层
    udp_protocol = (struct udp_header *)(packetData + 14 + 20);

    u_short sport = ntohs(udp_protocol->sport);
    u_short dport = ntohs(udp_protocol->dport);
    u_short datalen = ntohs(udp_protocol->datalen);

    printf("源端口: %5d --> 目标端口: %5d --> 大小: %5d \n", sport, dport,datalen);
}

TCPScanner::TCPScanner()
{
    Init();
}

void TCPScanner::TCP_Connect_Scan(const char *StartIP, const char *DestIP, unsigned short StartPort, unsigned short EndPort)
{
    clock_t StartTime, EndTime;
    float CostTime;

    //加载socket函数
    SOCKET sock;
    struct sockaddr_in server;

    TIMEVAL TimeOut;
    FD_SET mask;

    TimeOut.tv_sec = 0;
    TimeOut.tv_usec = 50;  //超时为50ms

    FD_ZERO(&mask);

    int CurrPort;	//当前端口
    int ret;
    unsigned long mode = 1;  //ioctlsocket函数的最后一个参数

    server.sin_family = AF_INET;	//指定地址格式，在winsock中只能使用AF_INET

    int startIp = ip2num(StartIP);
    int endIp = ip2num(DestIP);

    u_long ulDestIP = INADDR_NONE;
    StartTime = clock();
    for (CurrPort = StartPort; CurrPort <= EndPort; CurrPort++)
    {
        for(int ip = startIp; ip <= endIp; ip++)
        {
            sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            FD_SET(sock, &mask);
            ioctlsocket(sock, FIONBIO, &mode);

            ulDestIP = inet_addr(num2ip(ip).toStdString().c_str());
            if(ulDestIP == INADDR_NONE)
            {
                hostent* pHostent = gethostbyname(DestIP);
                if(pHostent)
                {
                    ulDestIP = (*(in_addr*)pHostent->h_addr).s_addr;
                }
                else
                {
                    assert(false);
                    cout << "错误" << endl;
                }
            }
            server.sin_addr.s_addr = ulDestIP;
            server.sin_addr.s_addr = inet_addr(num2ip(ip).toStdString().c_str());
            server.sin_port = htons(CurrPort);//指定被扫描的端口
            connect(sock, (struct sockaddr*)&server, sizeof(server));//进行连接

            ret = select(-1, NULL, &mask, NULL, &TimeOut);

            QVector<QString> item(4);//IP 端口号 状态 服务

            if (0 == ret || -1 == ret)
            {
                ::closesocket(sock);
            }
            else
            {
                item[0] = num2ip(ip);
                item[1] = QString::number(CurrPort);
                item[2] = "Open";
                item[3] = ::showservice(QString::number(CurrPort));
                OnResult.Broadcast(item);
                closesocket(sock);
            }
        }
    }
    EndTime = clock();
    CostTime = (float)(EndTime - StartTime) / CLOCKS_PER_SEC;
    printf("Cost time:%f second\n", CostTime);
    OnEnd.Broadcast();
}

void TCPScanner::TCP_Connect_Scan(const char *DestIP, unsigned short StartPort, unsigned short EndPort)
{
    TCP_Connect_Scan(DestIP, DestIP, StartPort, EndPort);
}

void GetMacAddress(std::string IP)
{
    PIP_ADAPTER_INFO pAdapterInfo;
    PIP_ADAPTER_INFO pAdapter = NULL;
    DWORD errValue = 0;
    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
    pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
    if (!pAdapterInfo)//malloc失败
        return;
    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) //空间不够，重新分配
    {
        free(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
        if (!pAdapterInfo) //malloc失败
            return;
    }

    if ((errValue = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
    {
        pAdapter = pAdapterInfo;
        int flag = 0;
        while (pAdapter)
        {
            IP_ADDR_STRING* pIpAddrString = &(pAdapter->IpAddressList);
            do
            {
                if(IP == pIpAddrString->IpAddress.String)
                {
                    m_gateIPAddress = pAdapter->GatewayList.IpAddress.String;
                    int offset = 0;
                    for (DWORD i = 0; i < pAdapter->AddressLength; i++)
                    {
                        if (i == (pAdapter->AddressLength - 1))
                            offset += sprintf(SourceMAC + offset, "%.2X\0", pAdapter->Address[i]);
                        else
                            offset += sprintf(SourceMAC + offset, "%.2X-", pAdapter->Address[i]);
                    }
                    flag = 1;
                    break;
                }
                pIpAddrString = pIpAddrString->Next;
            }while(pIpAddrString);
            pAdapter = pAdapter->Next;
            if(flag == 1) break;
        }
    }

    if (pAdapterInfo)
    {
        free(pAdapterInfo);
    }
}

void TCPScanner::TCP_Syn_Scan(const char *DestIP, unsigned short StartPort, unsigned short EndPort)
{
    // 填充地址并生成数据包包头
    ULONG pulMac[2] = {0};
    ULONG ulLen = 6;
    BYTE* bPhysAddr = NULL;
    DWORD dwRetVal = ::SendARP(inet_addr(m_gateIPAddress.c_str()), 0, &pulMac, &ulLen);

    if (dwRetVal != NO_ERROR) return;

    bPhysAddr = (BYTE*)&pulMac;
    if (ulLen)
    {
        int offset = 0;
        for (int i = 0; i < (int)ulLen; i++)
        {
            if (i == (int)(ulLen - 1))
                offset += sprintf(DestinationMAC + offset, "%.2X\0", (int)bPhysAddr[i]);
            else
                offset += sprintf(DestinationMAC + offset, "%.2X-", (int)bPhysAddr[i]);
        }
    }


    u_long ulDestIP = INADDR_NONE;
    if(strcmp("127.0.0.1", DestIP) == 0)
    {
        ulDestIP = inet_addr(IPAddress);
    }
    else
    {
        ulDestIP = inet_addr(DestIP);
    }

    if(ulDestIP == INADDR_NONE)
    {
        hostent* pHostent = gethostbyname(DestIP);
        if(pHostent)
        {
            ulDestIP = (*(in_addr*)pHostent->h_addr).s_addr;
        }
        else
        {
            assert(false);
            cout << "错误" << endl;
        }
    }

    ThreadPool::instance().commit([ulDestIP, StartPort, EndPort, this]{
        bpf_program fcode;
        char strFilter[300];
        memset(strFilter, 0, sizeof(strFilter));
        // sprintf(strFilter, "(tcp and (tcp[tcpflags] & (tcp-syn | tcp-rst) != 0)) and ((ip[12] * %u + ip[13] * %u + ip[14] * %u + ip[15]) >= %u) and ((ip[12] * %u + ip[13] * %u + ip[14] * %u + ip[15]) <= %u)",
        //         0x1000000, 0x10000, 0x100, inet_addr(SourceIP), 0x1000000, 0x10000, 0x100, ulDestIP);

        // sprintf(strFilter, "(tcp and (tcp[tcpflags] & (tcp-syn | tcp-rst) != 0)) and (ip src net %lu and ip dst net %lu)", inet_addr(SourceIP), ulDestIP);

        SOCKADDR_IN addr_tmp;
        addr_tmp.sin_addr.S_un.S_addr = ulDestIP;
        sprintf(strFilter, "(tcp and (tcp[tcpflags] & (tcp-syn | tcp-rst) != 0)) and (src portrange %hu-%hu) and (src host %s) and (dst host %s)", StartPort, EndPort, inet_ntoa(addr_tmp.sin_addr), IPAddress);

        // sprintf(strFilter, "(tcp and tcp[tcpflags] & (tcp-syn | tcp-rst) == (tcp-syn | tcp-rst)) and (src portrange 0-200)");

        if(pcap_compile(m_adhandle, &fcode, strFilter, 1, netmask))
        {
            QLOG_ERROR() << "编译失败";
            return;
        }

        if(0 > pcap_setfilter(m_adhandle, &fcode))
        {
            QLOG_ERROR() << "设置过滤器出错";
            return;
        }

        pcap_pkthdr *Packet_Header;    // 数据包头
        const u_char * Packet_Data;    // 数据本身
        int retValue;
        while((retValue = pcap_next_ex(m_adhandle, &Packet_Header, &Packet_Data)) >= 0)
        {
            if(bIsStopping)
            {
                break;
            }

            if(retValue == 0)
            {
                QLOG_INFO() << "处理超时";
                continue;
            }
            else
            {
                if(retValue == 1)
                {
                    PrintTCPHeader(Packet_Data);
                    struct _tcphdr* tcphdr = (struct _tcphdr *)(Packet_Data + 14 + 20);
                    u_short dstport = ntohs(tcphdr->th_dport);
                    u_short srcport = ntohs(tcphdr->th_sport);

                    if(dstport != 1234) return;
                    QVector<QString> item(4);
                    SOCKADDR_IN addr;
                    addr.sin_addr.S_un.S_addr = ulDestIP;

                    if((tcphdr->th_flag & 0x10) && (tcphdr->th_flag & 0x02))
                    {
                        item[0] = QString(inet_ntoa(addr.sin_addr));
                        item[1] = QString::number(srcport);
                        item[2] = "Open";
                        item[3] = ::showservice(QString::number(srcport));
                        OnSynResult.Broadcast(item);
                    }
                    else
                    {
                        item[0] = QString(inet_ntoa(addr.sin_addr));
                        item[1] = QString::number(srcport);
                        item[2] = "Close";
                        item[3] = ::showservice(QString::number(srcport));
                        OnSynResult.Broadcast(item);
                    }
                }
            }
        }
    });

    // 循环发包
    for (unsigned short CurPort = StartPort; CurPort <= EndPort; ++CurPort)
    {
        CreateTCPPacket(MACStringToBytes(SourceMAC), MACStringToBytes(DestinationMAC), inet_addr(SourceIP), ulDestIP,
                        atoi(SourcePort), CurPort, 2);

        if(m_adhandle == NULL || FinalPacket == NULL) return;
        int a = pcap_sendpacket(m_adhandle, FinalPacket, 54);
        if (0 != a)
        {
            char* szErr = pcap_geterr(m_adhandle);
            std::cout << a << szErr << std::endl;
        }
    }
}

void TCPScanner::SetSynStopping(bool bIsStop)
{
    bIsStopping = bIsStop;
}

void TCPScanner::TCP_Fin_Scan(const char *DestIP, unsigned short StartPort, unsigned short EndPort)
{
    // 填充地址并生成数据包包头
    ULONG pulMac[2] = {0};
    ULONG ulLen = 6;
    BYTE* bPhysAddr = NULL;
    DWORD dwRetVal = ::SendARP(inet_addr(m_gateIPAddress.c_str()), 0, &pulMac, &ulLen);

    if (dwRetVal != NO_ERROR) return;

    bPhysAddr = (BYTE*)&pulMac;
    if (ulLen)
    {
        int offset = 0;
        for (int i = 0; i < (int)ulLen; i++)
        {
            if (i == (int)(ulLen - 1))
                offset += sprintf(DestinationMAC + offset, "%.2X\0", (int)bPhysAddr[i]);
            else
                offset += sprintf(DestinationMAC + offset, "%.2X-", (int)bPhysAddr[i]);
        }
    }


    u_long ulDestIP = INADDR_NONE;
    if(strcmp("127.0.0.1", DestIP) == 0)
    {
        ulDestIP = inet_addr(IPAddress);
    }
    else
    {
        ulDestIP = inet_addr(DestIP);
    }

    if(ulDestIP == INADDR_NONE)
    {
        hostent* pHostent = gethostbyname(DestIP);
        if(pHostent)
        {
            ulDestIP = (*(in_addr*)pHostent->h_addr).s_addr;
        }
        else
        {
            assert(false);
            cout << "错误" << endl;
        }
    }

    ThreadPool::instance().commit([ulDestIP, StartPort, EndPort, this]{
        bpf_program fcode;
        char strFilter[300];
        memset(strFilter, 0, sizeof(strFilter));
        // sprintf(strFilter, "(tcp and (tcp[tcpflags] & (tcp-syn | tcp-rst) != 0)) and ((ip[12] * %u + ip[13] * %u + ip[14] * %u + ip[15]) >= %u) and ((ip[12] * %u + ip[13] * %u + ip[14] * %u + ip[15]) <= %u)",
        //         0x1000000, 0x10000, 0x100, inet_addr(SourceIP), 0x1000000, 0x10000, 0x100, ulDestIP);

        // sprintf(strFilter, "(tcp and (tcp[tcpflags] & (tcp-syn | tcp-rst) != 0)) and (ip src net %lu and ip dst net %lu)", inet_addr(SourceIP), ulDestIP);

        SOCKADDR_IN addr_tmp;
        addr_tmp.sin_addr.S_un.S_addr = ulDestIP;
        sprintf(strFilter, "(tcp and (tcp[tcpflags] & (tcp-syn | tcp-rst) != 0)) and (src portrange %hu-%hu) and (src host %s) and (dst host %s)", StartPort, EndPort, inet_ntoa(addr_tmp.sin_addr), IPAddress);

        // sprintf(strFilter, "(tcp and tcp[tcpflags] & (tcp-syn | tcp-rst) == (tcp-syn | tcp-rst)) and (src portrange 0-200)");

        if(pcap_compile(m_adhandle, &fcode, strFilter, 1, netmask))
        {
            QLOG_ERROR() << "编译失败";
            return;
        }

        if(0 > pcap_setfilter(m_adhandle, &fcode))
        {
            QLOG_ERROR() << "设置过滤器出错";
            return;
        }

        pcap_pkthdr *Packet_Header;    // 数据包头
        const u_char * Packet_Data;    // 数据本身
        int retValue;
        while((retValue = pcap_next_ex(m_adhandle, &Packet_Header, &Packet_Data)) >= 0)
        {
            if(bSynIsStopping)
            {
                break;
            }

            if(retValue == 0)
            {
                QLOG_INFO() << "处理超时";
                continue;
            }
            else
            {
                if(retValue == 1)
                {
                    PrintTCPHeader(Packet_Data);
                    struct _tcphdr* tcphdr = (struct _tcphdr *)(Packet_Data + 14 + 20);
                    u_short dstport = ntohs(tcphdr->th_dport);
                    u_short srcport = ntohs(tcphdr->th_sport);
                    if(dstport != 1234) return;

                    QVector<QString> item(4);
                    SOCKADDR_IN addr;
                    addr.sin_addr.S_un.S_addr = ulDestIP;

                    if((tcphdr->th_flag & 0x10) && (tcphdr->th_flag & 0x02))
                    {
                        item[0] = QString(inet_ntoa(addr.sin_addr));
                        item[1] = QString::number(srcport);
                        item[2] = "Open";
                        item[3] = ::showservice(QString::number(srcport));
                        OnFinResult.Broadcast(item);
                    }
                    else
                    {
                        item[0] = QString(inet_ntoa(addr.sin_addr));
                        item[1] = QString::number(srcport);
                        item[2] = "Close";
                        item[3] = ::showservice(QString::number(srcport));
                        OnFinResult.Broadcast(item);
                    }
                }
            }
        }
    });

    // 循环发包
    for (unsigned short CurPort = StartPort; CurPort <= EndPort; ++CurPort)
    {
        CreateTCPPacket(MACStringToBytes(SourceMAC), MACStringToBytes(DestinationMAC), inet_addr(SourceIP), ulDestIP,
                        atoi(SourcePort), CurPort, 1);

        if(m_adhandle == NULL || FinalPacket == NULL) return;
        int a = pcap_sendpacket(m_adhandle, FinalPacket, 54);
        if (0 != a)
        {
            char* szErr = pcap_geterr(m_adhandle);
            std::cout << a << szErr << std::endl;
        }
    }
}

void TCPScanner::SetFinStopping(bool bIsStop)
{
    bSynIsStopping = bIsStop;
}

void TCPScanner::UDP_Scan(const char *DestIP, unsigned short StartPort, unsigned short EndPort)
{
    // 填充地址并生成数据包包头
    ULONG pulMac[2] = {0};
    ULONG ulLen = 6;
    BYTE* bPhysAddr = NULL;
    DWORD dwRetVal = ::SendARP(inet_addr(m_gateIPAddress.c_str()), 0, &pulMac, &ulLen);

    if (dwRetVal != NO_ERROR) return;

    bPhysAddr = (BYTE*)&pulMac;
    if (ulLen)
    {
        int offset = 0;
        for (int i = 0; i < (int)ulLen; i++)
        {
            if (i == (int)(ulLen - 1))
                offset += sprintf(DestinationMAC + offset, "%.2X\0", (int)bPhysAddr[i]);
            else
                offset += sprintf(DestinationMAC + offset, "%.2X-", (int)bPhysAddr[i]);
        }
    }


    u_long ulDestIP = INADDR_NONE;
    if(strcmp("127.0.0.1", DestIP) == 0)
    {
        ulDestIP = inet_addr(IPAddress);
    }
    else
    {
        ulDestIP = inet_addr(DestIP);
    }

    if(ulDestIP == INADDR_NONE)
    {
        hostent* pHostent = gethostbyname(DestIP);
        if(pHostent)
        {
            ulDestIP = (*(in_addr*)pHostent->h_addr).s_addr;
        }
        else
        {
            assert(false);
            cout << "错误" << endl;
        }
    }

    ThreadPool::instance().commit([ulDestIP, StartPort, EndPort, this]{
        // bpf_program fcode;
        // char strFilter[300];
        // memset(strFilter, 0, sizeof(strFilter));
        // // sprintf(strFilter, "(tcp and (tcp[tcpflags] & (tcp-syn | tcp-rst) != 0)) and ((ip[12] * %u + ip[13] * %u + ip[14] * %u + ip[15]) >= %u) and ((ip[12] * %u + ip[13] * %u + ip[14] * %u + ip[15]) <= %u)",
        // //         0x1000000, 0x10000, 0x100, inet_addr(SourceIP), 0x1000000, 0x10000, 0x100, ulDestIP);

        // // sprintf(strFilter, "(tcp and (tcp[tcpflags] & (tcp-syn | tcp-rst) != 0)) and (ip src net %lu and ip dst net %lu)", inet_addr(SourceIP), ulDestIP);

        // SOCKADDR_IN addr_tmp;
        // addr_tmp.sin_addr.S_un.S_addr = ulDestIP;
        // sprintf(strFilter, "(tcp and (tcp[tcpflags] & (tcp-syn | tcp-rst) != 0)) and (src portrange %hu-%hu) and (src host %s) and (dst host %s)", StartPort, EndPort, inet_ntoa(addr_tmp.sin_addr), IPAddress);

        // // sprintf(strFilter, "(tcp and tcp[tcpflags] & (tcp-syn | tcp-rst) == (tcp-syn | tcp-rst)) and (src portrange 0-200)");

        // if(pcap_compile(m_adhandle, &fcode, strFilter, 1, netmask))
        // {
        //     QLOG_ERROR() << "编译失败";
        //     return;
        // }

        // if(0 > pcap_setfilter(m_adhandle, &fcode))
        // {
        //     QLOG_ERROR() << "设置过滤器出错";
        //     return;
        // }

        // pcap_pkthdr *Packet_Header;    // 数据包头
        // const u_char * Packet_Data;    // 数据本身
        // int retValue;
        // while((retValue = pcap_next_ex(m_adhandle, &Packet_Header, &Packet_Data)) >= 0)
        // {
        //     if(bIsStopping)
        //     {
        //         break;
        //     }

        //     if(retValue == 0)
        //     {
        //         QLOG_INFO() << "处理超时";
        //         continue;
        //     }
        //     else
        //     {
        //         if(retValue == 1)
        //         {
        //             PrintTCPHeader(Packet_Data);
        //             struct _tcphdr* tcphdr = (struct _tcphdr *)(Packet_Data + 14 + 20);
        //             u_short dstport = ntohs(tcphdr->th_dport);
        //             u_short srcport = ntohs(tcphdr->th_sport);

        //             if(dstport != 1234) return;
        //             QVector<QString> item(4);
        //             SOCKADDR_IN addr;
        //             addr.sin_addr.S_un.S_addr = ulDestIP;

        //             if((tcphdr->th_flag & 0x10) && (tcphdr->th_flag & 0x02))
        //             {
        //                 item[0] = QString(inet_ntoa(addr.sin_addr));
        //                 item[1] = QString::number(srcport);
        //                 item[2] = "Open";
        //                 item[3] = ::showservice(QString::number(srcport));
        //                 OnSynResult.Broadcast(item);
        //             }
        //         }
        //     }
        // }
    });

    // 循环发包
    for (unsigned short CurPort = StartPort; CurPort <= EndPort; ++CurPort)
    {
        CreateUDPPacket(MACStringToBytes(SourceMAC), MACStringToBytes(DestinationMAC), inet_addr(SourceIP), ulDestIP,
                        atoi(SourcePort), CurPort, NULL, 0);

        if(m_adhandle == NULL || FinalPacket == NULL) return;
        int a = pcap_sendpacket(m_adhandle, FinalPacket, 42);
        if (0 != a)
        {
            char* szErr = pcap_geterr(m_adhandle);
            std::cout << a << szErr << std::endl;
        }
    }
}

void TCPScanner::Init()
{
    // 打开网卡
    OpenAdapter(IPAddress);
    GetMacAddress(IPAddress);
}
